import 'package:flutter/material.dart';

/// 弹幕点击事件回调
typedef XhDanmuTapCallback = void Function(XhDanmuItem item);
typedef XhDanmuDoubleTapCallback = void Function(XhDanmuItem item);

/// 弹幕状态枚举
enum XhDanmuItemState {
  normal, // 正常状态
  highlighted, // 高亮状态
  clicked, // 被点击状态
  disabled, // 禁用状态
}

/// 抽象弹幕组件基类
abstract class XhDanmuComponent {
  /// 唯一标识符
  final String id;

  /// 弹幕状态
  XhDanmuItemState state;

  /// 是否可点击
  final bool clickable;

  /// 扩展数据
  final Map<String, dynamic>? extra;

  XhDanmuComponent({
    required this.id,
    this.state = XhDanmuItemState.normal,
    this.clickable = false,
    this.extra,
  });

  /// 获取组件宽度 - 必须实现（高度由轨道配置决定）
  double getWidth();

  /// 获取组件尺寸 - 高度固定为轨道高度
  Size getSize(double trackHeight) {
    return Size(getWidth(), trackHeight);
  }

  /// 构建Widget - 必须实现，组件需要适应给定的高度约束
  Widget buildWidget(
    BuildContext context,
    double maxHeight,
    VoidCallback? onTap,
    VoidCallback? onDoubleTap,
  );

  /// 点击事件处理（可选重写）
  void onTapHandler() {}

  /// 双击事件处理（可选重写）
  void onDoubleTapHandler() {}
}

/// XH弹幕轨道
class XhDanmuTrack {
  final int trackId;
  final double topOffset;
  final double height;
  final double minSpacing;

  // 活跃弹幕列表（按时间顺序排列）
  final List<XhDanmuItem> activeDanmuList = [];

  // 等待队列
  final List<XhDanmuItem> waitingQueue = [];

  XhDanmuTrack({
    required this.trackId,
    required this.topOffset,
    required this.height,
    required this.minSpacing,
  });

  /// 获取轨道负载分数（用于轨道选择）
  double get loadScore {
    // 综合考虑活跃弹幕数量和队列长度
    return activeDanmuList.length * 2.0 + waitingQueue.length * 1.0;
  }

  /// 获取轨道状态
  XhDanmuTrackStatus get status {
    if (activeDanmuList.isEmpty && waitingQueue.isEmpty) {
      return XhDanmuTrackStatus.idle;
    } else if (activeDanmuList.length <= 2 && waitingQueue.isEmpty) {
      return XhDanmuTrackStatus.normal;
    } else {
      return XhDanmuTrackStatus.busy;
    }
  }

  /// 清空轨道
  void clear() {
    activeDanmuList.clear();
    waitingQueue.clear();
  }

  /// 检查是否可以添加新弹幕（严格碰撞检测）
  bool canAddDanmu(double containerWidth, double currentTime, double newDanmuWidth) {
    if (activeDanmuList.isEmpty) return true;

    // 找到最后一个（最右边的）弹幕
    final lastDanmu = activeDanmuList.last;

    // 计算最后弹幕当前的右边缘位置
    final lastDanmuCurrentX = lastDanmu.calculatePosition(containerWidth, currentTime);
    final lastDanmuRightEdge = lastDanmuCurrentX + lastDanmu.logicalWidth;

    // 新弹幕从容器右边缘开始
    final newDanmuStartX = containerWidth;

    // 计算实际间距
    final actualSpacing = newDanmuStartX - lastDanmuRightEdge;

    return actualSpacing >= minSpacing;
  }
}

/// 轨道状态枚举
enum XhDanmuTrackStatus {
  idle, // 空闲
  normal, // 正常
  busy, // 繁忙
}

/// XH弹幕逻辑项 - 包装自定义组件的逻辑容器
class XhDanmuItem {
  final String id;
  final double speed;
  final XhDanmuComponent component; // 自定义弹幕组件

  // 轨道信息
  int trackId;

  // 时间信息
  double startTime;
  double? endTime; // 预计完全离开屏幕的时间

  // 位置信息
  double? currentX;

  // 状态标记
  bool isActive = false;
  bool isCompleted = false;

  XhDanmuItem({
    required this.id,
    required this.speed,
    required this.component,
    required this.trackId,
    required this.startTime,
    this.currentX,
  });

  /// 获取组件的逻辑宽度（用于碰撞检测）
  double get logicalWidth => component.getWidth();

  /// 获取组件状态
  XhDanmuItemState get state => component.state;

  /// 设置组件状态
  set state(XhDanmuItemState newState) => component.state = newState;

  /// 是否可点击
  bool get clickable => component.clickable;

  /// 计算当前位置
  double calculatePosition(double containerWidth, double currentTime) {
    if (!isActive) return containerWidth;

    final elapsedTime = currentTime - startTime;
    final moveDistance = elapsedTime * speed;
    return containerWidth - moveDistance;
  }

  /// 计算预期的结束时间（完全离开屏幕的时间）
  void calculateEndTime(double containerWidth) {
    // 弹幕需要移动的总距离：从容器右边缘到完全离开左边缘
    final totalDistance = containerWidth + logicalWidth;
    final totalTime = totalDistance / speed;
    endTime = startTime + totalTime;
  }

  /// 检查是否完全离开屏幕（严格检测）
  bool isCompletelyOffScreen(double containerWidth) {
    final currentPos = currentX ?? containerWidth;
    // 只有当弹幕的右边缘完全移出屏幕左边界时才算离屏
    return currentPos + logicalWidth < 0;
  }

  /// 检查是否在屏幕上可见
  bool isVisible(double containerWidth) {
    final currentPos = currentX ?? containerWidth;
    // 弹幕的任何部分在屏幕范围内就算可见
    return currentPos < containerWidth && currentPos + logicalWidth > 0;
  }

  /// 获取弹幕的右边缘位置
  double getRightEdge() {
    return (currentX ?? 0) + logicalWidth;
  }

  // 移除了 getStateColor 和 getStateFontSize 方法
  // 视觉效果现在由外部 Widget Builder 处理

  /// 复制弹幕项
  XhDanmuItem copyWith({
    String? id,
    double? speed,
    XhDanmuComponent? component,
    int? trackId,
    double? startTime,
    double? endTime,
    double? currentX,
    bool? isActive,
    bool? isCompleted,
  }) {
    return XhDanmuItem(
      id: id ?? this.id,
      speed: speed ?? this.speed,
      component: component ?? this.component,
      trackId: trackId ?? this.trackId,
      startTime: startTime ?? this.startTime,
      currentX: currentX ?? this.currentX,
    )
      ..endTime = endTime ?? this.endTime
      ..isActive = isActive ?? this.isActive
      ..isCompleted = isCompleted ?? this.isCompleted;
  }
}

/// 弹幕配置类 - 只包含核心布局和性能配置
class XhDanmuConfig {
  /// 轨道数量
  final int trackCount;

  /// 每条轨道高度
  final double trackHeight;

  /// 轨道间距
  final double trackSpacing;

  /// 弹幕间最小间距（像素）
  final double minSpacing;

  /// 弹幕移动速度（像素/秒）
  final double speed;

  /// 动画更新频率（FPS）
  final int targetFps;

  const XhDanmuConfig({
    this.trackCount = 5,
    this.trackHeight = 40.0,
    this.trackSpacing = 8.0,
    this.minSpacing = 20.0,
    this.speed = 50.0,
    this.targetFps = 60,
  });

  /// 计算轨道的顶部偏移
  double getTrackTopOffset(int trackIndex) {
    return trackIndex * (trackHeight + trackSpacing);
  }

  /// 根据容器高度计算动态轨道高度
  double calculateDynamicTrackHeight(double containerHeight) {
    // 减去所有轨道间距后，剩余高度均分给轨道
    final totalSpacing = (trackCount - 1) * trackSpacing;
    final availableHeight = containerHeight - totalSpacing;
    return (availableHeight / trackCount).clamp(20.0, double.infinity);
  }

  /// 根据容器高度计算动态轨道顶部偏移
  double getDynamicTrackTopOffset(int trackIndex, double containerHeight) {
    final dynamicTrackHeight = calculateDynamicTrackHeight(containerHeight);
    return trackIndex * (dynamicTrackHeight + trackSpacing);
  }

  /// 计算弹幕容器的总高度
  double get totalHeight {
    return trackCount * trackHeight + (trackCount - 1) * trackSpacing;
  }

  /// 复制配置
  XhDanmuConfig copyWith({
    int? trackCount,
    double? trackHeight,
    double? trackSpacing,
    double? minSpacing,
    double? speed,
    int? targetFps,
  }) {
    return XhDanmuConfig(
      trackCount: trackCount ?? this.trackCount,
      trackHeight: trackHeight ?? this.trackHeight,
      trackSpacing: trackSpacing ?? this.trackSpacing,
      minSpacing: minSpacing ?? this.minSpacing,
      speed: speed ?? this.speed,
      targetFps: targetFps ?? this.targetFps,
    );
  }
}

/// 弹幕系统状态
class XhDanmuStatus {
  final bool isPlaying;
  final double currentTime;
  final double containerWidth;
  final int totalActiveDanmu;
  final int totalQueuedDanmu;
  final List<XhDanmuTrackInfo> trackInfos;

  const XhDanmuStatus({
    required this.isPlaying,
    required this.currentTime,
    required this.containerWidth,
    required this.totalActiveDanmu,
    required this.totalQueuedDanmu,
    required this.trackInfos,
  });
}

/// 轨道信息
class XhDanmuTrackInfo {
  final int trackId;
  final int activeDanmuCount;
  final int queuedDanmuCount;
  final XhDanmuTrackStatus status;
  final double loadScore;

  const XhDanmuTrackInfo({
    required this.trackId,
    required this.activeDanmuCount,
    required this.queuedDanmuCount,
    required this.status,
    required this.loadScore,
  });
}
